# Main Iteration Algorithm
# -----------------------------------------------------------------------------
function iterate_VF(ce::CE_Economy_M; tol_max=5e-4, penalty_Π_val=1e-5)
# -----------------------------------------------------------------------------

#Load previous solution (if option is requested)
Load_Solution(ce::CE_Economy_M)


iter, dist, dist_q_abs      = 0, 10.0, 10.0;
penalty_Π                   = 0.;

while iter < ce.maxiter && (dist > tol_max || iter<25)

      iter = iter+1

      # ------------------------------------------------------------------------
      # Compute expected values (does not include the transition matrix)
      EW_P, EW_I  = compute_EV(ce, ce.WP), compute_EV(ce, ce.WI);
      EQ_P, EQ_I  = compute_EV(ce, ce.QP), compute_EV(ce, ce.QI);
      # ------------------------------------------------------------------------

      # ------------------------------------------------------------------------
      #Solve for optimal policies: bp, π, d. Update value functions
      dist_bp_abs,dist_bp_norm,dist_π_norm   = solve_main(ce, EW_P, EW_I, penalty_Π=penalty_Π);
      dist_W_norm, dist_W_abs, dist_def_abs  = solve_default(ce, EW_P, EW_I, EQ_P, EQ_I);
      # ------------------------------------------------------------------------
      # ------------------------------------------------------------------------
      #Compute Conjectures and Prices
      dist_def_bel_abs, dist_def_bel_norm,  dist_Π_bel_abs,dist_Π_bel_norm   = CONJECTURE_fx(ce);
      dist_q_norm,      dist_q_abs                                           = compute_prices(ce);
      # ------------------------------------------------------------------------

      # ------------------------------------------------------------------------
      #Compute total (max) distance
      dist_ValFx_Prices       = max(dist_W_norm,  dist_q_norm)*20;                    
      dist_Policies_Beliefs   = max(dist_bp_norm, dist_π_norm,  dist_def_bel_norm, dist_Π_bel_norm);
      dist    	            = max(dist_ValFx_Prices, dist_Policies_Beliefs);
      # ------------------------------------------------------------------------
      #Small penalty for misreport policiy
      penalty_Π  = ifelse(dist_ValFx_Prices<5e-4  && iter>700, penalty_Π_val, penalty_Π);
      #Iterate only on prices to speed up convergence
      if iter%50==0
      for i=1:10
      dist_q_norm, dist_q_abs = compute_prices(ce);
      end
      end

      # ------------------------------------------------------------------------
      ratio_p  = ifelse(ce.nz==2,200,100)
      if (iter%ratio_p==0  || iter==ce.maxiter)
      println(dist)
      @printf("iter %.3g, DIST_W_norm %.3g, DIST_W_abs %.3g, DIST_q_norm %.3g, DIST_q_abs %.3g, DIST_bp_abs %.3g, DIST_bp_norm %.3g, DIST_ΠB_bel %.3g, DIST_ΠB_bel_norm %.3g, DIST_def_norm %.3g, dist_π_norm %.3g, penalty_π %.3g\n", iter, dist_W_norm,  dist_W_abs, dist_q_norm, dist_q_abs, dist_bp_abs, dist_bp_norm, dist_Π_bel_abs, dist_Π_bel_norm, dist_def_bel_norm, dist_π_norm, penalty_Π)
      end
      # ------------------------------------------------------------------------


end # while

#Message if reached convergence
#------------------------------
if iter<ce.maxiter
println("REACHED CONVERGENCE")
@printf("iter %.3g, distf %.3g\n", iter, dist)
end
# -----------------------------------------------------------------------------
# -----------------------------------------------------------------------------

#SAVE REULTS [only for calibration purposes]
# ------------------------------------------------------------------------
if ce.save_start == 1
      string_save = "CE_model_start.jld"
      if length(ce.z_grid)==2
      string_save = "CE_model_Chatterjee_start.jld"
      end
save(string("model_data/",string_save),
           "WId", ce.WId,      "WIr", ce.WIr,  "WI", ce.WI,  "WP", ce.WP,  "WPd", ce.WPd,  "WPr", ce.WPr,
           "QP", ce.QP, "QI", ce.QI,
           "q_mat",ce.q_mat,           "bpI", ce.bpI,   "bpP", ce.bpP,
           "default_I", ce.default_I,  "default_P", ce.default_P,
           "Π_exp", ce.Π_exp ,  "πpol", ce.πpol,
           "default_I_bel",  ce.default_I_bel, "default_P_bel", ce.default_P_bel);
end
# ------------------------------------------------------------------------

# ------------------------------------------------------------------------
#Compute Secondary Markets Prices
# ------------------------------------------------------------------------
Iterate_qA(ce)
# ------------------------------------------------------------------------

Void
end #function
# ------------------------------------------------------------------------
